package com.xl6667.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xl6667.constants.SystemConstants;
import com.xl6667.domain.ResponseResult;
import com.xl6667.domain.dto.MenuDto;
import com.xl6667.domain.dto.RoleMenuDto;
import com.xl6667.domain.dto.RoleMenuTreeselectDto;
import com.xl6667.domain.entity.Menu;
import com.xl6667.domain.entity.RoleMenu;
import com.xl6667.enums.AppHttpCodeEnum;
import com.xl6667.mapper.MenuMapper;
import com.xl6667.service.MenuService;
import com.xl6667.service.RoleMenuService;
import com.xl6667.util.BeanCopyUtil;
import com.xl6667.util.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author 熊磊
* @description 针对表【sys_menu(菜单权限表)】的数据库操作Service实现
* @createDate 2024-03-21 13:22:01
*/
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu>
    implements MenuService {
    @Autowired
    private RoleMenuService roleMenuService;
    @Override
    public List<String> selectPermsByUserId(Long id) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Menu::getMenuType, SystemConstants.MENU,SystemConstants.BUTTON);
        queryWrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMA);
        //如果用户id为1，为超级管理员有所有权限
        if(id == 1L){
            return list(queryWrapper).stream().map(Menu::getPerms).collect(Collectors.toList());
        }
        //不是查询
        return getBaseMapper().selectPermsByUserId(id);
    }

    @Override
    public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        //判断是否是管理员
        if(SecurityUtil.isAdmin() || userId == 1L){
            //如果是 获取所有符合要求的Menu
            menus = menuMapper.selectAllRouterMenu();
        }else{
            //否则  获取当前用户所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }
        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        return builderMenuTree(menus,0L);
    }

    @Override
    public ResponseResult getMenuList(String menuName, String status) {

        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(menuName),Menu::getMenuName,menuName);
        queryWrapper.eq(StringUtils.hasText(status),Menu::getStatus,status);
        queryWrapper.eq(Menu::getDelFlag,SystemConstants.DEL_FLAG_NORMA);

        List<Menu> list = list(queryWrapper);
        List<MenuDto> menuDtos = BeanCopyUtil.copyBeanList(list, MenuDto.class);
        return ResponseResult.okResult(menuDtos);

    }

    @Override
    public ResponseResult addMenu(Menu menu) {
        save(menu);
        return ResponseResult.okResult("添加成功");
    }

    @Override
    public ResponseResult getMenu(Long id) {
        Menu menu = getById(id);
        MenuDto menuDto = BeanCopyUtil.copyBean(menu, MenuDto.class);
        return ResponseResult.okResult(menuDto);
    }

    @Override
    public ResponseResult putMenu(Menu menu) {
        if (menu.getId().equals(menu.getParentId())){
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR,"修改菜单"+menu.getMenuName()+"失败，上级菜单不能选择自己");
        }
        updateById(menu);
        return ResponseResult.okResult("修改成功");

    }

    @Override
    public ResponseResult delMenu(Long id) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getParentId,id);
        List<Menu> list = list(queryWrapper);
        if (!Objects.isNull(list) && list.size()>0){
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR,"存在子菜单不允许删除");
        }
        LambdaUpdateWrapper<Menu> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Menu::getId,id).set(Menu::getDelFlag,SystemConstants.DEL_FLAG);
        update(null,updateWrapper);
        return ResponseResult.okResult("删除成功");
    }

    @Override
    public ResponseResult getTreeselect() {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getDelFlag,SystemConstants.DEL_FLAG_NORMA);
        queryWrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMA);

        List<Menu> menus = list(queryWrapper);
        List<Menu> menus1 = builderMenuTree(menus, 0L);

        return ResponseResult.okResult(menuChangeRoleMenu(menus1));

    }

    @Override
    public ResponseResult getRoleMenuTreeselect(Long id) {
        List<Long> longList = null;
        LambdaQueryWrapper<Menu> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Menu::getDelFlag,SystemConstants.DEL_FLAG_NORMA);
        queryWrapper1.eq(Menu::getStatus,SystemConstants.STATUS_NORMA);
        if (id == 1L){
            longList = list(queryWrapper1).stream().map(Menu::getId).collect(Collectors.toList());
        }else {
            LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RoleMenu::getRoleId,id);
            longList = roleMenuService.list(queryWrapper).stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        }


        List<Menu> menus = list(queryWrapper1);
        List<Menu> menus1 = builderMenuTree(menus, 0L);
        List<RoleMenuDto> roleMenuDtos = menuChangeRoleMenu(menus1);

        RoleMenuTreeselectDto roleMenuTreeselectDto = new RoleMenuTreeselectDto(roleMenuDtos,longList);
        return ResponseResult.okResult(roleMenuTreeselectDto);

    }

    private static List<RoleMenuDto> menuChangeRoleMenu(List<Menu> menus1) {
        return menus1.stream().map(menu -> {
            RoleMenuDto roleMenuDto = new RoleMenuDto();
            roleMenuDto.setId(menu.getId());
            roleMenuDto.setLabel(menu.getMenuName());
            roleMenuDto.setParentId(menu.getParentId());
            if (menu.getChildren()!=null){
                roleMenuDto.setChildren(menuChangeRoleMenu(menu.getChildren()));
            }
            return roleMenuDto;
        }).collect(Collectors.toList());
    }

    private List<Menu> builderMenuTree(List<Menu> menus, Long parentId) {
        List<Menu> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .map(menu -> menu.setChildren(getChildren(menu, menus)))
                .collect(Collectors.toList());
        return menuTree;
    }

    /**
     * 获取存入参数的 子Menu集合
     * @param menu
     * @param menus
     * @return
     */
    private List<Menu> getChildren(Menu menu, List<Menu> menus) {
        List<Menu> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m->m.setChildren(getChildren(m,menus)))
                .collect(Collectors.toList());
        return childrenList;
    }
}




